import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Esta clase representa al objeto que crea barcos, los pone en el tablero y dirige la colocacion <p>
 * de los mismos.
 * 
 * @author Miguel Martinez Aguilar
 * @version 10 de Mayo del 2013
 */
public class CreaFlota extends ScrollActor
{
    // Declaracion de variables de instancia
    private Barco[] barco;// es un arreglo de barcos.
    private Tablero tab;// es el tablero donde se agregaran los barcos.
    private Colocador colocador;// Es el objeto colocador, el cual colocara los barcos.
    private FijaBarco ancla;// es el boton que fijara permanentemente los barcos.
    private GiraBarco girador;// es el boton que girara el barco a colocar.
    private int aux;// es un auxiliar contador de los barcos colocados en el tablero.
    private Panel panel;// es el panel de juego.
    private boolean derecha;// boleano que indica a CreaFlota a que lista del Evaluador se agregaran los barcos.
    private boolean oculto;// boleano que indica si los barcos estaran ocultos.
    private BarcoImg bimg;// es el objeto imagen que representara al barco.
    
    /**
     * Este es el constructor de CreaFlota.
     * @param tab: el tablero donde se colocaran los barcos.
     * @param panel: el panel al que hara referencia este objeto.
     * @param derecha: boleano que indica a CreaFlota a que lista del Evaluador se agregaran los barcos.
     * @param ocultos: boleano que indica si los barcos estaran ocultos.
     */
    public CreaFlota(Tablero tab, Panel panel, boolean derecha, boolean ocultos) 
    {
        aux = 0;
        int aux2 = 1;
        this.barco = new Barco[10];
        for( int i = 4; i >= 1; i--){
            for( int j = 1; j <= aux2; j++){
                barco[aux] = new Barco(i,panel.evaluador());
                aux++;
            }
            aux2++;
        }
        this.tab = tab;
        colocador = new Colocador(tab.entregaMatriz(),this);
        aux = 0;
        ancla = new FijaBarco(this);
        girador = new GiraBarco(this);
        this.panel = panel;
        this.derecha = derecha;
        bimg = null;
        this.oculto = ocultos;
    }
    
    /**
     * Este metodo prepara a CreaFlota para ingresar los barcos de forma manual.<p>
     * se debe ejecutar este metodo antes de la colocacion de los barcos.
     * @param aleatorio: boleano que indica a CreaFlota si los barcos se agregaran de <p>
     * forma aleatoria o manual
     */
    public void preparar(boolean aleatorio) 
    {
        ScrollWorld mundo = super.getWorld();// este metodo nos permite acceder al mundo
        this.agregaObj(colocador, this.getX(), this.getY());
        mundo.addObject(girador, this.getX() + 82, this.getY() - 20);
        mundo.addObject(ancla, this.getX() + 82, this.getY() + 23);
        this.enviaBarco();
        colocador.esAleatorio(aleatorio);
        colocador.activar();
    }
    
    /**
     * Este metodo envia un barco al colocador.
     */
    public void enviaBarco()
    {
        if(aux < 10){
            this.creaBarcoImg(barco[aux].longitud());
            panel.agregaBarco(barco[aux],bimg,derecha);
            barco[aux].vertical(girador.esVertical());
            colocador.tomaBarco(barco[aux]);
            aux++;
        }
        else this.seElimina();
    }
    
    
    /**
     * Este metodo crea las imagenes de los barcos.
     * @param longitud: numero que indica la longitud del barco.
     */
    public void creaBarcoImg(int longitud)
    {
        ScrollWorld mundo = super.getWorld();
        if(longitud == 1)bimg = new P(oculto);
        if(longitud == 2)bimg = new M(oculto);
        if(longitud == 3)bimg = new G(oculto);
        if(longitud == 4)bimg = new E(oculto);
        mundo.addObject(bimg,this.getX(),this.getY());
    }  
    
    /**
     * Este metodo elimina este objeto.
     */
    public void seElimina()
    {
        ScrollWorld mundo = super.getWorld();
        colocador.seElimina();
        mundo.removeObject(ancla);
        mundo.removeObject(girador);
        panel.comienzajuego();
        mundo.removeObject(this);// con este metodo eliminamos un objeto del mundo
    }
    
    /**
     * Este metodo cambia la orientacion del barco.
     * @param vertical: boleano que indica si el barco en turno sera vertical u horizontal.
     */
    public void vertical(boolean vertical)
    {
        barco[aux - 1].vertical(vertical);
        colocador.ubicaBarco();
    }
    
    /**
     * Este metodo cambia la orientacion del boton GiraBarco.
     * @param val: boleano que indica si el boton GiraBarco sera vertical u horizontal.
     */
    public void giraBarco(boolean val)
    {
        girador.esVertical(val);
    }    
    
    /**
     * Este metodo fija el barco en turno a la matriz del tablero.
     */
    public void fijaBarco()
    {
        barco[aux - 1].quedaFijo();
    }
    
    /**
     * Este metodo pregunta si la posicion del barco es valida en el tablero. <p>
     * Regresa un boleano que indica si los espacios del barco son validos.
     */
    public boolean barcoValido()
    {
        return colocador.sonValidos();
    }
    
    /**
     * Este metodo activa o desactiva el boton FijaBarco.
     * @param val: boleano que indica si el boton FijaBarco estara activo o desactivo.
     */
    public void activaAncla(boolean val)
    {
        ancla.activaAncla(val);
    }
    
    /**
     * Este metodo pide al boton FijaBarco que se ejecute.
     */
    public void anclaBarco()
    {
        ancla.ejecuta();
    }
}